import json

import requests
from datetime import datetime
import time

import base64
import sys

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Hash import SHA256, SHA1
from Crypto.Signature import pss
from PyQt5.QtWidgets import QMessageBox

public_key = "-----BEGIN PUBLIC KEY-----\n MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsy4xppPDUT2eAOR5h0cyydzxtKB9O80A\n GjUT6FmDgg6CwelpnE0C2h2JQyP1gCveJs6GDwSDn20RVVpD67f//YPYErjaH/CBOxNG3k5IkW1o\n Qx04uqFNMtWvjzk0aFh2eJLsBi7Ha4elw3WySg00B8oZCL4VBay4ML9kyOAjjCj5jHCX8a2yxIMJ\n IF+EjW3kBR68IMwBvuDL45Qa0oB24vTffaSEs+hGjMTQvoCciOfti3pmEAlVc438/cBgAhK5cIMf\n IMElxYAVvmsDy0I7RCUTrajetKjX94Q+JuQUxnIHNC3IVtYsl1x0lNRtb93IhlRCkZ9djOu350eq\n hZIOXQIDAQAB\n  -----END PUBLIC KEY-----"

# bl_quantity = 报价服务  20gp = twenty_gp_quantity  40gp = forty_gp_quantity 40hq= forty_hq  percentage=最低5% 下单预付款
def api_searchfee(auth_token, product_id, bl_quantity = 0, twenty_gp_quantity=0, forty_gp_quantity=0, forty_hq_quantity=0, percentage=5):
        product_res = requests.get(
            'https://synconhub.coscoshipping.com/api/product/client/sailing/product/%s' % (product_id), headers={
                'X-Auth-Token': auth_token
        })
        if (product_res.status_code != 200):
            print(product_res.json())
        product_json = product_res.json()
        product_data = {
            "porCity": product_json['porCity'],
            "polPort": product_json['polPort'],
            "podPort": product_json['podPort'],
            "scheduleData": product_json['scheduleData']['destination'],
        }

        effectiveTime = product_json['etd']
        timeArray = time.strptime(effectiveTime, "%Y-%m-%d %H:%M")
        time1 = datetime(year=timeArray.tm_year, month=timeArray.tm_mon, day=timeArray.tm_mday, hour=timeArray.tm_hour,
                         minute=timeArray.tm_min)
        effectiveTime = time1.strftime('%Y-%m-%dT%H:%M:%S.000Z')
        print(effectiveTime)
        # 请求产品附加费用
        fee_payload = json.dumps([
            {
                "key": 1,
                "isPreBookingOrder": False,
                "chargeTag": "POR",
                "chargeModel": "BOTH",
                "svcLoopCode": "A3C",
                "tradeAreaCode": product_json['insuredRule']['tradeAreaCode'],
                "tradeLaneCode": product_json['tradeLaneCode'],
                "direction": product_json['direction'],
                "effectiveTime": effectiveTime,  # 必须要加上时间，不然得到费用不全
                "por": product_data['porCity']['id'],  # polPort.city.id
                "pol": product_data['polPort']['id'],  # polPort.id
                "pod": product_data['podPort']['id'],  # podPort  city.id
                "fnd": product_data['scheduleData']['id'],  # scheduleData.destination.id
                "channelCode": product_json['channelCode'],
                "commodityCode": product_json['commodityCode'],
                "cargoCategory": product_json['cargoCategory'],
                "cntrInfo": [
                    {
                        "cntrSize": "40GP",
                        "amount": 1
                    },
                    {
                        "cntrSize": "20GP",
                        "amount": 1
                    },
                    {
                        "cntrSize": "40HQ",
                        "amount": 1
                    }
                ],
                "transhipmentPortIds": [
                ],
                "paymentTerms": "P"
            },
            {
                "key": 2,
                "chargeTag": "FND",
                "chargeModel": "BOTH",
                "svcLoopCode": "A3C",
                "tradeAreaCode": product_json['insuredRule']['tradeAreaCode'],
                "tradeLaneCode": product_json['tradeLaneCode'],
                "direction": product_json['direction'],
                "effectiveTime": effectiveTime,  # 必须要加上时间，不然得到费用不全
                "por": product_data['porCity']['id'],  # polPort.city.id
                "pol": product_data['polPort']['id'],  # polPort.id
                "pod": product_data['podPort']['id'],  # podPort  city.id
                "fnd": product_data['scheduleData']['id'],  # scheduleData.destination.id
                "cntrInfo": [
                    {
                        "cntrSize": "40GP",
                        "amount": 1
                    },
                    {
                        "cntrSize": "20GP",
                        "amount": 1
                    },
                    {
                        "cntrSize": "40HQ",
                        "amount": 1
                    }
                ]
            }
        ])
        searchfee_res = requests.post(
            "https://synconhub.coscoshipping.com/api/common/feeUpload/searchfee",
            headers={
                "X-Auth-Token": auth_token,
                "Content-Type": "application/json;charset=UTF-8"
        }, data=fee_payload)
        fee_data = searchfee_res.json()  #附加费用
        print("=======附加服务费=======")
        print(searchfee_res.json())
        #下单参数
        order_data = {"order": {}, "orderPromotionUsageParam": [], "operations": []};
        order_data['order']["prodId"] = product_id
        order_data['order']["sailingProdType"] = "I"
        order_data['order']['channelCode'] = 'GENERAL'
        order_data['order']['cargoCategory'] = 'GENERAL'
        order_data['order']['prodType'] = 'SAILING_PROD'
        order_data['order']['reeferValueAddServices'] = []
        order_data['order']['tradeLaneCode'] = product_json['tradeLaneCode']

        order_data['order']['orderItems'] = [
            {
                "itemType": "CNTR",
                "cntrType": "20GP",
                "quantity": twenty_gp_quantity,
                "orderItemCharges" : [],
                "cargoValue" : 0,
            },
            {
                "itemType": "CNTR",
                "cntrType": "40GP",
                "quantity": forty_gp_quantity,
                "orderItemCharges": [],
                "cargoValue": 0,
            },
            {
                "itemType": "CNTR",
                "cntrType": "40HQ",
                "quantity": forty_hq_quantity,  # 订单
                "orderItemCharges": [],
                "cargoValue": 0,
            },
            {
                "itemType": "BL",  # 保价服务
                "quantity": bl_quantity,  # 保价
                "orderItemCharges": [],
                "cargoValue": 0,
            }
        ]
        twenty_gp = []  #20gp 提交数据
        twenty_gp.append(
        {
            "chargeName": "海运费",
            "chargeCode": None,
            "chargeType": "OCEAN_FEE",
            "price": product_json['containerOceanFeeMap']['20GP'],
            "currency": "USD",
            "toCurrency": "CNY",
            "transitPortId": None,
            "paymentTermsType": "P"
        }
        )
        for i in fee_data[0]['chargeInfo'][1]['chargeDetail']:
            temp = {
                "chargeName": i['chargeName'],
                "chargeCode": i['chargeCode'],
                "chargeType": i['chargeType'],
                "chargeHisId": i['chargeHisId'],
                "price": i['price'],
                "currency": i['currency'],
                "toCurrency": "CNY",
                "transitPortId": None,
                "paymentTermsType": i['paymentTerms'],
                "include": i['include']
            };
            twenty_gp.append(temp)
        order_data['order']['orderItems'][0]['orderItemCharges'] = twenty_gp
        forty_gp = []; #40gp提交的数据
        forty_gp.append(
        {
            "chargeName": "海运费",
            "chargeCode": None,
            "chargeType": "OCEAN_FEE",
            "price": product_json['containerOceanFeeMap']['40GP'],
            "currency": "USD",
            "toCurrency": "CNY",
            "transitPortId": None,
            "paymentTermsType": "P"
        })
        for i in fee_data[0]['chargeInfo'][2]['chargeDetail']:
            temp = {
                "chargeName": i['chargeName'],
                "chargeCode": i['chargeCode'],
                "chargeType": i['chargeType'],
                "chargeHisId": i['chargeHisId'],
                "price": i['price'],
                "currency": i['currency'],
                "toCurrency": 'CNY',
                "transitPortId": None,
                "paymentTermsType": i['paymentTerms'],
                "include": i['include']
            };
            forty_gp.append(temp)
        order_data['order']['orderItems'][1]['orderItemCharges'] = forty_gp
        #40HQ
        forty_hq = []
        forty_hq.append(
            {
                "chargeName": "海运费",
                "chargeCode": None,
                "chargeType": "OCEAN_FEE",
                "price": product_json['containerOceanFeeMap']['40HQ'],
                "currency": "USD",
                "toCurrency": 'CNY',
                "transitPortId": None,
                "paymentTermsType": "P"
            })
        for i in fee_data[0]['chargeInfo'][3]['chargeDetail']:
            temp = {
                "chargeName": i['chargeName'],
                "chargeCode": i['chargeCode'],
                "chargeType": i['chargeType'],
                "chargeHisId": i['chargeHisId'],
                "price": i['price'],
                "currency": i['currency'],
                "toCurrency": 'CNY',
                "transitPortId": None,
                "paymentTermsType": i['paymentTerms'],
                "include": i['include']
            };
            forty_hq.append(temp)

        order_data['order']['orderItems'][2]['orderItemCharges'] = forty_hq

        # 保价服务
        bl_data = []
        for i in fee_data[0]['chargeInfo'][0]['chargeDetail']:
            temp = {
                "chargeName": i['chargeName'],
                "chargeCode": i['chargeCode'],
                "chargeType": i['chargeType'],
                "chargeHisId": i['chargeHisId'],
                "price": i['price'],
                "currency": i['currency'],
                "toCurrency": 'CNY',
                "transitPortId": None,
                "paymentTermsType": i['paymentTerms'],
                "include": i['include']
            };
            bl_data.append(temp)
        order_data['order']['orderItems'][3]['orderItemCharges'] = bl_data
        #下单预付款
        if(percentage):
            order_data['order']['paymentPercentage'] = percentage
            order_data['order']['totalPricePercentage'] = percentage
        order_data['order']['paymentInfo'] = {}
        # dejson = json.dumps(order_data,ensure_ascii=False)
        print("下单参数")
        print(order_data)
        return order_data


def api_order_pay(self, token, order_payload, pwd:str = 123123):
    print("请求下单接口")
    client_order_req = requests.post(
        "https://synconhub.coscoshipping.com/api/product/client/order",
        headers={
            "X-Auth-Token": token,
            "Accept": "application/json, text/plain, */*",
            "Content-Type": "application/json"
        }, json=order_payload)
    if client_order_req.status_code != 200:
        print(client_order_req.content)
        return

    print(client_order_req)
    print(client_order_req.json())
    client_order = client_order_req.json()
    self.textlog("生成订单: %s" % (client_order['orderNo']))
    #获取订单详情
    order_info_req = requests.get("https://synconhub.coscoshipping.com/api/product/client/order/prepay-info",
        headers={
              "X-Auth-Token": token,
              "Accept": "application/json, text/plain, */*",
              "Content-Type": "application/json"
        },
         params={
             "orderNo" : client_order_req.json()['orderNo'],
             "isExtraCharge": False
     })
    print("订单详情")
    print(order_info_req)
    print(order_info_req.json())
    if order_info_req.status_code != 200:
        print(client_order_req.json())
        return
    order_info = order_info_req.json()
    orderNo = order_info['orderNo']
    orderId = order_info['orderId']
    scac = order_info['scac']
    payment_detail_req = requests.get("https://synconhub.coscoshipping.com/api/product/client/order-payment/detail",  headers={
            "X-Auth-Token": token,
            "Content-Type": "application/x-www-form-urlencoded"
        },params={
        "productOrderType": "SAILING_PROD",
        "orderNo": orderNo,
    })
    print("获取订单详情")
    print(payment_detail_req)
    if payment_detail_req.status_code != 200:
        print(payment_detail_req.content)
        return
    payment_detail= payment_detail_req.json()
    amount = payment_detail['SAILING_PROD']['amount']
    orderType = payment_detail['SAILING_PROD']['orderType']
    self.textlog("支付金额： %d" % (amount))
    payload = {
        "accountInfo": {
            "payWay": "PREPAID",
            "password": str(pwd_rsa_encrypt(str(pwd))),
            "unionPayType": "COMPANY",
            "scac": scac
        },
        "sailingProdOrderInfo": {
            "paymentOrderType": orderType,
            "orderNo": orderNo,
            "amount": amount
        }
    }
    print("支付参数")
    print(payload)
    pay_req = requests.put("https://synconhub.coscoshipping.com/api/product/client/order-payment/pay",
       headers={
           "X-Auth-Token": token,
           "Accept": "application/json, text/plain, */*",
           "Content-Type": "application/json"
       },
       json=payload)

    if pay_req.status_code != 200:
        self.textlog(pay_req.json()['message'])
        QMessageBox.information(self,'提示', pay_req.json()['message'], QMessageBox.Yes)
        return False

    return True

#密码加密
def pwd_rsa_encrypt(message):
    """校验RSA加密 使用公钥进行加密"""
    cipher = PKCS1_OAEP.new(key=RSA.importKey(public_key), hashAlgo=SHA256, mgfunc=lambda x,y: pss.MGF1(x,y, SHA1))
    cipher_text = base64.b64encode(cipher.encrypt(message.encode("utf-8")))
    return cipher_text


airway_items = ["宁波-横滨", "宁波-多伦多", "宁波-温哥华"]
airway = [
    {
        #宁波 - 横滨
        'porCityId': '738872886232879',
        'fndCityId': '738872886235553',
    },
    {
        # 宁波 - 多伦多
        'porCityId': '738872886232879',
        'fndCityId': '738872886232879',
    },
    {
        # 宁波 - 温哥华
        'porCityId': '738872886232879',
        'fndCityId': '738872886236623',
    }
]
def buildProduct(airway_idx, startDate, endDate):
    payload = {
        "channelCode": "GENERAL",
        "prodType": "I",
        "startDate": startDate,
        "cargoCategory": "GENERAL",
        "porCityId": airway[airway_idx]['porCityId'],
        "fndCityId": airway[airway_idx]['fndCityId'],
        "endDate": endDate,
        "page": 1,
        "size": 30
    }
    return payload

if __name__ == '__main__':
    auth_token = '3dca063a-633d-4e6a-b25c-540239c99f87'
    api_searchfee(auth_token, '8aaa2a367941cef701794560d13e3a19', bl_quantity=1, forty_gp_quantity=1)